package org.grottarossa.ui.core.casemanagement.bpm;

import java.util.ArrayList;
import java.util.ResourceBundle;

import org.grottarossa.template.data.enums.EnumWorkItemType;
import org.grottarossa.template.data.pojo.workflows.Activity;
import org.grottarossa.template.data.pojo.workflows.WorkItem;
import org.grottarossa.template.data.pojo.workflows.Workflow;
import org.grottarossa.template.drivers.DriverException;
import org.grottarossa.ui.core.ApplicationSession;
import org.grottarossa.ui.core.base.IBaseComponent;
import org.grottarossa.ui.core.i18n.DM;

import com.vaadin.ui.Window;
import com.vaadin.ui.Window.CloseEvent;
import com.vaadin.ui.Window.CloseListener;
import com.vaadin.ui.Window.Notification;

public class WorkflowStarter implements CloseListener
{
	private static final long serialVersionUID = 4104252982204212121L;
	private Workflow m_workflow;
	private IBaseComponent m_view;
	protected ResourceBundle m_localizer = DM.instance().
		getBundle(WorkflowStarter.class.getPackage().getName() + ".Resources");
	private WorkItem m_workItem;

	private Window m_popup;
	private Window m_actualWindow;
	private final ArrayList<IAction> m_onTerminateActions;
	private final ApplicationSession m_appSession;

	public WorkflowStarter(ApplicationSession appSession, IBaseComponent view, ArrayList<IAction> onTerminateActions)
	{
		this.m_appSession = appSession;
		m_view = view;
		this.m_onTerminateActions = (onTerminateActions != null) ? onTerminateActions : new ArrayList<IAction>();
		m_actualWindow = view.getWindow();
	}

	public boolean setWorkflow(Workflow workflow, String workItemId)
	{
		try
		{
			m_workflow = workflow;
			m_workItem = m_appSession.getBuilder().getWorkflowManagement().getWorkItem(workflow.getWorkflowId(), workflow.getWorkflowVersion(), workItemId);
		}
		catch (DriverException e)
		{
			e.printStackTrace();
			m_view.getApplication().getMainWindow().showNotification(
					m_localizer.getString("notify.startprocess.caption"),
					m_localizer.getString("notify.startprocess.description.KO"),
					Notification.TYPE_ERROR_MESSAGE);
			return false;
		}

		return true;
	}

	public boolean setWorkflow(Workflow workflow)
	{
		try
		{
			m_workflow = workflow;
			m_workItem = m_appSession.getBuilder().getWorkflowManagement().executeWorkflow(m_workflow);
		}
		catch (DriverException e)
		{
			e.printStackTrace();
			m_view.getApplication().getMainWindow().showNotification(
					m_localizer.getString("notify.startprocess.caption"),
					m_localizer.getString("notify.startprocess.description.KO"),
					Notification.TYPE_ERROR_MESSAGE);
			return false;
		}

		return true;
	}

	public EnumWorkItemType getWorkItemType()
	{
		return m_workItem.getWorkItemType();
	}

	public void start(boolean showInPopup)
	{
		try
		{
			if (m_workItem.isLockedBy(m_appSession.getBuilder().getIdentity().getUser()))
			{
				Activity activity = m_appSession.getBuilder().getWorkflowManagement().getActivity(
						m_workflow, m_workItem);

				BaseBPMPanel bpmPanel;

				if (showInPopup)
				{
					ArrayList<IAction> onCloseActions = new ArrayList<IAction>();
					onCloseActions.add(new ClosePopupAction());

					for(IAction a : m_onTerminateActions)
					{
						onCloseActions.add(a);
					}

					bpmPanel = new BaseBPMPanel(m_appSession, m_workItem, activity, m_view, onCloseActions, m_workflow);

					m_popup = m_view.showInPopup(bpmPanel, 640, 480, m_workflow.getWorkflowName(), true, true);
					m_popup.addListener(this);
				}
				else
				{
					bpmPanel = new BaseBPMPanel(m_appSession, m_workItem, activity, m_view, m_onTerminateActions, m_workflow);
					m_view.showInDetailArea(bpmPanel);
				}

				bpmPanel.setWidth("100%");
				bpmPanel.setHeight("100%");

				m_view.getApplication().getMainWindow().showNotification(
						m_localizer.getString("notify.startprocess.caption"),
						m_localizer.getString("notify.startprocess.description.OK"),
						Notification.TYPE_TRAY_NOTIFICATION);
			}
		}
		catch (Exception e)
		{
			m_view.showError(m_localizer.getString("notify.startprocess.description.KO"));
		}
	}

	private class ClosePopupAction implements IAction
	{
		public void execute()
		{
			m_actualWindow.removeWindow(m_popup);
		}
	}

	public void windowClose(CloseEvent e)
	{
		//Se il workflow viene eseguito in un popup qui si gestisce la chiusura del popup
		//da pulsante [x]
		for(IAction a : m_onTerminateActions)
		{
			a.execute();
		}
	}
}
